#include <QDir>
#include <QMenu>
#include <QTimer>
#include <QPixmap>
#include <QProcess>
#include <QSettings>
#include <QTableView>
#include <QMessageBox>
#include <QStandardPaths>
#include <QStandardItemModel>

#include "itemdelegate.h"
#include "ui_debugform.h"
#include "ui_mainform.h"
#include "ui_baseform.h"
#include "ui_xtcpform.h"
#include "debugform.h"
#include "debugform.h"
#include "tableview.h"
#include "frpconfig.h"
#include "debugform.h"
#include "QCloseEvent"
#include "mainform.h"
#include "baseform.h"
#include "xtcpform.h"

const QString exeNew  = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.frp/frpc.exe";
const QString iniNew  = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.frp/frpc.ini";
const QString frpPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.frp";

MainForm::MainForm(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainForm)
{
    ui->setupUi(this);
    baseform    = new baseForm() ;baseform->mainw  = this;
    xtcpform    = new xtcpForm() ;xtcpform->mainw  = this;
    debugform   = new debugForm();debugform->mainw = this;
    frpConfig   = new FrpConfig();frpConfig->mainw = this;
    settings    = new QSettings("frp","main");
    process     = new QProcess(this);
    statusLabel = new QLabel(this);
    image       = new QPixmap();
    micon       = new QSystemTrayIcon(this);
    miconExit   = new QAction("退出",this);
    miconShow   = new QAction("设置",this);
    m_timer     = new QTimer();
    m_menu      = new QMenu(this);

    pageInit();                                //页面初始化
    passwordMode();                            //token密码隐藏
    fileStarInit();                            //释放文件
    if(settings->value("setup").toInt() == 1)  //判断软件是否为第一次启动。第一次启动不加载注册表文件
        recData();                             //恢复文件
    getApplicationCfg();                       //预读取软件配置

    //*********任务栏图标************//
    image->load(":/img/nok.png");
    micon->setIcon(QIcon(*image));
    micon -> show();
    micon->setToolTip("frp管理");
    connect(mShow,&QAction::triggered,this,&MainForm::show);
    connect(micon,&QSystemTrayIcon::activated,this,&MainForm::on_activatedSysTrayIcon);
    micon->showMessage("frpManage",
                       "请在系统托盘打开设置",
                       QSystemTrayIcon::Information,
                       200);
    creatMenu();

    /**************自启****************/
    if(ui->setupCheckBox->checkState() == Qt::Checked){ //自启
        on_startButton_clicked();
        if(runState == 0){
            statusLabel->setText("启动失败...正在重连...");
            ui->statusbar->addWidget(statusLabel);
            m_timer->start(20000);//开机后延迟20s启动连接，防止电脑网络未初始化导致连接失败
        }
        connect(m_timer, &QTimer::timeout, this, &MainForm::on_m_Timeout);
        setProcessAutoRun(QApplication::applicationFilePath(),1);
    }
    else{
        setProcessAutoRun(QApplication::applicationFilePath(),0);
        statusLabel->setText("未连接...");
        ui->statusbar->addWidget(statusLabel);
    }
    this->setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint);
    ui->LOGO->setPixmap(QPixmap(":/img/ok.png"));
    ui->LOGO->setScaledContents(true);
}
void MainForm::on_m_Timeout(){
    static int16_t failCount = 0;
    if(runState == 1){ //如果已连接
        m_timer->stop();
        return;
    }
    process->close();
    failCount++;
    on_startButton_clicked(); //尝试连接
    statusLabel->setText("启动失败...尝试第" + QString::number(failCount) + "次重连....");
    ui->statusbar->addWidget(statusLabel);
    if(failCount > 3 ){
        statusLabel->setText("连接失败,请检查网络或配置...");
        ui->statusbar->addWidget(statusLabel);
        process->close();
        m_timer->stop();
        micon->showMessage("frpManage",
                           "frp服务启动失败，请检查网络或设置",
                           QSystemTrayIcon::Information,
                           -1);
    }
}
void MainForm::closeEvent(QCloseEvent *event )
{
    event->ignore();
    this->hide();
}


MainForm::~MainForm(){
    process->close();
    process->kill();
    saveData();
    settings->setValue("setup",1);
    delete ui;
    APPclrear();
}

//************功能按键***************//
void MainForm::on_startButton_clicked(){
    if(runState == 0){
        getApplicationCfg();                                                                                      //获取配置
        frpConfig->setFrpConfig(frpConfig->setCFG(getRdNum(baseform->baseTable),getRdNum(xtcpform->xtcpTable)));  //生成ini文件
        process->start(exeNew,QStringList("-c" +iniNew ));
        process->waitForFinished(1000);
        result = QString::fromLocal8Bit(process->readAllStandardOutput());//读取运行结果
        if(result.indexOf("failed") == -1 &&  result.indexOf("error") == -1 && result.indexOf("success") != -1 ){//启动成功
            runState = 1;
            ui->startButton->setText("停止");
            baseform->ui->startButton->setText("停止");
            xtcpform->ui->startButton->setText("停止");
            debugform->ui->startButton->setText("停止");
            ui->addrLineEdit->setEnabled(false);
            ui->portLineEdit->setEnabled(false);
            ui->tokenLineEdit->setEnabled(false);
            statusLabel->setText("启动成功");
            ui->statusbar->addWidget(statusLabel);
            micon->showMessage("frpManage",
                               "启动成功",
                               QSystemTrayIcon::Information,
                               100);


            image->load(":/img/ok.png");
            micon->setIcon(QIcon(*image));
            saveData();
            baseform->saveData();
            xtcpform->saveData();


        }
        else{ //启动失败
            runState = 0;
            process->close();
            process->kill();
            statusLabel->setText("启动失败");
            ui->statusbar->addWidget(statusLabel);
        }

        debugTmp = debugTmp.append(result);
        debugform->ui->DebugTextEdit->setText(debugTmp);
        return;
    }
    if( runState == 1){
        process->close();
        process->kill();
        runState = 0;
        statusLabel->setText("已断开连接...");
        ui->statusbar->addWidget(statusLabel);
        ui->startButton->setText("启动");
        baseform->ui->startButton->setText("启动");
        xtcpform->ui->startButton->setText("启动");
        debugform->ui->startButton->setText("启动");
        ui->addrLineEdit->setEnabled(true);
        ui->portLineEdit->setEnabled(true);
        ui->tokenLineEdit->setEnabled(true);
        image->load(":/img/nok.png");
        micon->setIcon(QIcon(*image));
        return;
    }
}

void MainForm::on_ResetButton_clicked(){
    process->close();
    runState = 0;
    on_startButton_clicked();
}

/******获取所有配置**********/
void MainForm::getApplicationCfg(){
    /*主页配置*/
    frpCommon.addr  = ui ->  addrLineEdit -> text();
    frpCommon.port  = ui ->  portLineEdit -> text();
    frpCommon.token = ui -> tokenLineEdit -> text();
    /*base*/
    getBaseCfg();
    /*xtcp*/
    getXtcpCfg();
}

//*****************获取激活的rd数量******************
qint8 MainForm::getRdNum(TableView *tmp){
    qint8 tableCol = 0; // 添加的行数
    for(int i = 0 ; i < tmp->model->rowCount() ; i++ )
        if( tmp->GetItemData(i,0) == "true"){
            tableCol++;
        }
    return tableCol;
}

/*获取表格的内容*/
void MainForm::getBaseCfg(){
    qint16 cout = 0;
    for( int i = 0; i <  baseform->baseTable->model->rowCount() ; i++){
        if(baseform->baseTable->GetItemData(i,base_sw) == "false"){
            cout++;
            continue;
        }
        frpBase[i-cout].name            = baseform->baseTable->GetItemData(i,base_name);
        frpBase[i-cout].ip              = baseform->baseTable->GetItemData(i,base_ip);
        frpBase[i-cout].type            = baseform->baseTable->GetItemData(i,base_type);
        frpBase[i-cout].localPort       = baseform->baseTable->GetItemData(i,base_local);
        frpBase[i-cout].remotePort      = baseform->baseTable->GetItemData(i,base_remote);
        frpBase[i-cout].use_encryption  = baseform->baseTable->GetItemData(i,base_encryption);
        frpBase[i-cout].use_compression = baseform->baseTable->GetItemData(i,base_compression);
    }
}
void MainForm::getXtcpCfg(){
    qint16 cout = 0;
    for( int i = 0; i <  xtcpform->xtcpTable->model->rowCount() ; i++){
        if(xtcpform->xtcpTable->GetItemData(i,xtcp_sw) == "false"){
            cout++;
            continue;
        }
        frpXtcp[i-cout].name            = xtcpform->xtcpTable->GetItemData(i,xtcp_name);
        frpXtcp[i-cout].ip              = xtcpform->xtcpTable->GetItemData(i,xtcp_ip);
        frpXtcp[i-cout].sORc            = xtcpform->xtcpTable->GetItemData(i,xtcp_sORc);
        frpXtcp[i-cout].port            = xtcpform->xtcpTable->GetItemData(i,xtcp_port);
        frpXtcp[i-cout].sk              = frpXtcp[i-cout].name + "password";//xtcpform->xtcpTable->GetItemData(i,xtcp_sk);
        frpXtcp[i-cout].use_encryption  = xtcpform->xtcpTable->GetItemData(i,xtcp_encryption);
        frpXtcp[i-cout].use_compression = xtcpform->xtcpTable->GetItemData(i,xtcp_compression);
    }
}

//***************软件开启复制文件*********************
void MainForm::fileStarInit(){
    const QString frpExePath = ":/frp/frpc.exe";
    const QString frpIniPath = ":/frp/frpc.ini";
    QFile FfrpExePath(frpExePath);
    QFile FfrpIniPath(frpIniPath);

    QFile FexeNew(exeNew);
    QFile FiniNew(iniNew);

    QDir dir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
    dir.mkdir(".frp");

    if (FexeNew.open(QIODevice::WriteOnly) && FiniNew.open(QIODevice::WriteOnly) ) {
        QByteArray tmp;
        if (FfrpExePath.open(QIODevice::ReadOnly)){
           tmp = FfrpExePath.readAll();
           FexeNew.write(tmp);
        }
        if (FfrpIniPath.open(QIODevice::ReadOnly)){
           tmp = FfrpIniPath.readAll();
           FiniNew.write(tmp);
        }
    }
    FexeNew.close();
    FiniNew.close();
    FfrpExePath.close();
    FfrpIniPath.close();
}

//************关闭软件后删除相关文件*****************
void MainForm::APPclrear(){

        QFile::remove(exeNew);
        QFile::remove(iniNew);

        QDir qDir(frpPath);
        qDir.removeRecursively();
}

/***************功能页面选择按键*************/
void MainForm::on_mainPushButton_clicked(){
    ui->stackedWidget->setCurrentWidget(ui->page);
}
void MainForm::on_basePushButton_clicked(){
    ui->stackedWidget->setCurrentWidget(baseform);
}
void MainForm::on_xtcpPushButton_clicked(){
    ui->stackedWidget->setCurrentWidget(xtcpform);
}
void MainForm::on_debugPushButton_clicked(){
    ui->stackedWidget->setCurrentWidget(debugform);
}
/*页面初始化*/
void MainForm::pageInit(){
    /*页面添加*/
    ui->stackedWidget->setCurrentWidget(ui->page);//设置默认页
    ui->stackedWidget->addWidget(baseform);       //添加窗口
    ui->stackedWidget->addWidget(xtcpform);
    ui->stackedWidget->addWidget(debugform);
    ui->portLineEdit->setText("7000");
}
void MainForm::passwordMode(){
    ui->tokenLineEdit->setContextMenuPolicy(Qt::NoContextMenu);             //设置无右键菜单
    ui->tokenLineEdit->setPlaceholderText(QString::fromLocal8Bit("token")); //设置密码提示
    ui->tokenLineEdit->setEchoMode(QLineEdit::Password);                    //设置密码隐藏
}


/*******保存和恢复************/
void MainForm::saveData(){
    settings->setValue("addrLineEdit", ui->addrLineEdit ->text());
    settings->setValue("portLineEdit", ui->portLineEdit ->text());
    settings->setValue("tokenLineEdit",ui->tokenLineEdit->text());
    settings->setValue("setupCheckBox",ui->setupCheckBox->checkState());
}

void MainForm::recData(){
    ui->addrLineEdit->setText(settings->value("addrLineEdit").toString());
    ui->portLineEdit->setText(settings->value("portLineEdit").toString());
    ui->tokenLineEdit->setText(settings->value("tokenLineEdit").toString());
    //ui->setupCheckBox->setCheckState(settings->value("setup"));
    qint8 checkState = settings->value("setupCheckBox").toInt();
    if(checkState == 0){
        ui->setupCheckBox->setCheckState(Qt::Unchecked);
    }
    else {
       ui->setupCheckBox->setCheckState(Qt::Checked);
    }
}

/*开机启动配置*/
#define AUTO_RUN "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
void MainForm::setProcessAutoRun(const QString &appPath,bool flag)
{
    QSettings settings(AUTO_RUN, QSettings::NativeFormat);

    //以程序名称作为注册表中的键,根据键获取对应的值（程序路径）
    QFileInfo fInfo(appPath);
    QString name = fInfo.baseName();    //键-名称

    //如果注册表中的路径和当前程序路径不一样，则表示没有设置自启动或本自启动程序已经更换了路径
    QString oldPath = settings.value(name).toString(); //获取目前的值-绝对路劲
    QString newPath = QDir::toNativeSeparators(appPath);    //toNativeSeparators函数将"/"替换为"\"
    if(flag)
    {
        if (oldPath != newPath)
            settings.setValue(name, newPath);
    }
    else
       settings.remove(name);
}

void MainForm::on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason){
    switch (reason) {
    case QSystemTrayIcon::DoubleClick: //双击显示
        this->show();
        break;

    default:
        break;
    }
}
/*托盘右键菜单添加和动作*/
void MainForm::creatMenu(){
    m_menu->addAction(miconShow);
    m_menu->addSeparator();
    m_menu->addAction(miconExit);
    m_menu->addSeparator();
    micon->setContextMenu(m_menu);

    connect(miconShow,&QAction::triggered,this,[this]{
        this->show();
    });
    connect(miconExit,&QAction::triggered,this,[this]{
        qApp->exit();
    });
}



